// ignore_for_file: depend_on_referenced_packages

import 'dart:ffi';

import 'package:flutter_2b_client/json/LocalDateTimeConverter.dart';
import 'package:flutter_2b_client/model/IntIdAndName.dart';
import 'package:flutter_2b_client/utils/local_datetime.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:retrofit/dio.dart';
import 'package:retrofit/http.dart';
import 'package:dio/dio.dart';

import '../utils/Page.dart';
import 'Initial.dart';

part 'MarketOrderApi.g.dart';

part 'MarketOrderApi.freezed.dart';

@RestApi()
abstract class MarketOrderApi {

  factory MarketOrderApi(Dio dio, {String baseUrl}) = _MarketOrderApi;

  @DELETE("/markets/orders/{id}")
  Future<void> deleteById(@Path("id") int id);

  @GET("/markets/{id}/orders")
  Future<Slice<QueryMarketOrderInMarketResponse>> queryMarketOrderInMarket(
      @Path("id") int marketId, Pageable pageable);

  @GET("/markets/orders/{orderId}")
  Future<MarketOrderDetail> getMarketOrderDetail(@Path("orderId") int orderId);

  @GET("/markets/orders/{orderId}/items")
  Future<Page<OrderItemInOrderSummary>> queryOrderItemsInOrder(
      @Path("orderId") int orderId, @Queries() Map<String, dynamic> queries);

  @DELETE("/markets/orders/{orderId}/items/{goodsId}")
  Future<void> deleteOrderItem(
      @Path("orderId") int orderId, @Path("goodsId") int goodsId);

  @PATCH("/markets/orders/{orderId}/items/{goodsId}/amount")
  Future<void> updateOrderItemGoodsAmount(
      @Path("orderId") int orderId,
      @Path("goodsId") int goodsId,
      @Body() UpdateItemAmountRequest updateItemAmountRequest);

  @GET("/markets/orders/{orderId}/items/barcodes/{barcode}/exists")
  Future<bool> exists(
      @Path("orderId") int orderId, @Path("barcode") String barcode);

  @POST("/markets/orders/{orderId}/items/barcodes/{barcode}")
  Future<OrderItemInOrderSummary> addItemFromBarcode(
      @Path("orderId") int orderId, @Path("barcode") String barcode);

  @PATCH("/markets/orders/{orderId}/submit")
  Future<void> submitMarketOrder(@Path("orderId") int orderId);

  @POST("/markets/orders/{orderId}/items/goods/{goodsId}")
  Future<OrderItemInOrderSummary> addItemFromGoodsId(
      @Path("orderId") int orderId, @Path("goodsId") int goodsId);

  @POST("/markets/{marketId}/orders")
  Future<int> createOrder(@Path("marketId") int marketId);

  @PATCH("/markets/orders/{orderId}/confirm")
  Future<void> confirmMarketOrder(@Path("orderId") int orderId);

  @GET("/markets/orders/{orderId}/excel")
  @DioResponseType(ResponseType.bytes)
  Future<List<int>> exportToExcel(@Path() int orderId);

}

@freezed
class QueryGoodsUnitResponse with _$QueryGoodsUnitResponse{

  const factory QueryGoodsUnitResponse({
    required int id,
    required String name,
    required int basicMultiple,
  }) = _QueryGoodsUnitResponse;

  const QueryGoodsUnitResponse._();

  factory QueryGoodsUnitResponse.fromJson(Map<String, dynamic> json) => _$QueryGoodsUnitResponseFromJson(json);

  bool get isBasicUnit{
    return basicMultiple==0;
  }

}

enum MarketOrderStatus{
  WAIT_SUBMIT,
  SUBMITTED,
  DELIVERY;

  String get displayString {
    switch (this) {
      case MarketOrderStatus.WAIT_SUBMIT:
        return "待提交";
      case MarketOrderStatus.SUBMITTED:
        return "已提交";
      case MarketOrderStatus.DELIVERY:
        return "已出货";
    }
  }
}

@freezed
class UpdateItemAmountRequest with _$UpdateItemAmountRequest {
  const factory UpdateItemAmountRequest({
    required int amount,
    int? unitId
  }) = _UpdateItemAmountRequest;

  const UpdateItemAmountRequest._();

  factory UpdateItemAmountRequest.fromJson(Map<String, dynamic> json) =>
      _$UpdateItemAmountRequestFromJson(json);
}

@freezed
class OrderItemInOrderSummary with _$OrderItemInOrderSummary {
  const factory OrderItemInOrderSummary({
    required int goodsId,
    required String name,
    required String barcode,
    required int amountInOrder,
    required int inStore,
    String? boxSpecification,
    IntIdAndName? unit,
    @Default([])
    List<QueryGoodsUnitResponse> units,
  }) = _OrderItemInOrderSummary;

  const OrderItemInOrderSummary._();

  factory OrderItemInOrderSummary.fromJson(Map<String, dynamic> json) =>
      _$OrderItemInOrderSummaryFromJson(json);
}

@freezed
class MarketOrderDetail with _$MarketOrderDetail {
  const factory MarketOrderDetail({
    required int id,
    required String number,
    @LocalDateTimeConverter() required LocalDateTime createdDateTime,
    required IntIdAndName createdBy,
    required IntIdAndName market,
    @LocalDateTimeConverter() LocalDateTime? submitDateTime,
    @LocalDateTimeConverter() LocalDateTime? deliveryDateTime,
  }) = _MarketOrderDetail;

  const MarketOrderDetail._();

  factory MarketOrderDetail.fromJson(Map<String, dynamic> json) =>
      _$MarketOrderDetailFromJson(json);
}

MarketOrderApi marketOrderApi = MarketOrderApi(dio, baseUrl: baseUrl);

@freezed
class QueryMarketOrderInMarketResponse with _$QueryMarketOrderInMarketResponse {
  const factory QueryMarketOrderInMarketResponse(
      {required int id,
      required IntIdAndName createdBy,
      @LocalDateTimeConverter() required LocalDateTime createdDateTime,
      @LocalDateTimeConverter() LocalDateTime? lastModifiedDateTime,
        required MarketOrderStatus status,
      required int goodsKindAmount}) = _QueryMarketOrderInMarketResponse;

  const QueryMarketOrderInMarketResponse._();

  factory QueryMarketOrderInMarketResponse.fromJson(
          Map<String, dynamic> json) =>
      _$QueryMarketOrderInMarketResponseFromJson(json);
}
